package main

import (
	"fmt"
	"math"
	"sort"
)

const PI float64 = math.Pi

// 定义接口，用于计算面积
type CalculateArea interface {
	Area() float64
}

// 定义圆形
type Circular struct {
	Radius float64
}

// 定义三角形
type Triangle struct {
	Bottom float64
	Height float64
}

// 定义长方形
type Rectangle struct {
	Width  float64
	Length float64
}

func (c *Circular) Area() float64 {
	// return PI * c.Radius * c.Radius
	return PI * math.Pow(c.Radius, 2)
}

func (r *Rectangle) Area() float64 {
	return r.Length * r.Width
}

func (t *Triangle) Area() float64 {
	return 0.5 * t.Bottom * t.Height
}

// 使用内置排序
func UseBuildinSort(gSlices []CalculateArea) {
	sort.Slice(gSlices, func(i, j int) bool {
		return gSlices[i].Area() > gSlices[j].Area()
	})
	fmt.Println("使用内置降序排序后:")
	for index := range gSlices {
		fmt.Printf("%+v,%+v\n", gSlices[index], gSlices[index].Area())
	}
}

// 定义自己的排序

type MySliceSortByArea []CalculateArea

func (x MySliceSortByArea) Len() int {
	return len(x)
}

func (x MySliceSortByArea) Swap(i, j int) {
	x[i], x[j] = x[j], x[i]
}

func (x MySliceSortByArea) Less(i, j int) bool {
	return x[i].Area() > x[j].Area()
}
func UserMySortByArea(gSlices []CalculateArea) {
	fmt.Println("使用自定义降序排序后:")
	sort.Sort(MySliceSortByArea(gSlices))
	for index := range gSlices {
		fmt.Printf("%+v,%+v\n", gSlices[index], gSlices[index].Area())
	}
}

func main() {
	c := &Circular{Radius: 3.5}
	t := &Triangle{Bottom: 3, Height: 5}
	r := &Rectangle{Width: 3, Length: 5}
	fmt.Printf("圆形的面积:%+v\n", c.Area())
	fmt.Printf("三角形的面积:%+v\n", t.Area())
	fmt.Printf("长方形的面积:%+v\n", r.Area())

	gSlices := []CalculateArea{
		&Circular{Radius: 3.5},
		&Circular{Radius: 1.5},
		&Triangle{Bottom: 4, Height: 10},
		&Rectangle{Width: 5, Length: 15},
		&Triangle{Bottom: 8, Height: 10},
		&Rectangle{Width: 12, Length: 15},
		&Rectangle{Width: 25, Length: 15},
		&Rectangle{Width: 19.6, Length: 18.09},
		&Rectangle{Width: 29.3, Length: 15.564},
		&Circular{Radius: 10.589},
		&Triangle{Bottom: 1.2, Height: 2.1},
	}
	fmt.Println("排序前:")
	for index := range gSlices {
		fmt.Printf("%+v,%+v\n", gSlices[index], gSlices[index].Area())
	}

	UseBuildinSort(gSlices)
	UserMySortByArea(gSlices)

}
